package com.dayatang.hrm.compensation.domain;

import java.util.Date;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

import com.dayatang.commons.domain.AbstractEntity;
import com.dayatang.commons.domain.InstanceFactory;
import com.dayatang.hrm.organisation.domain.Organization;

/**
 * 薪水册
 * 
 * @author chencao
 * 
 */
/**
 * @author pm
 * 
 */
@Entity
@Table(name = "pay_salary_pay_roll")
public class PayRoll extends AbstractEntity {

	/**
	 * 
	 */
	private static final long serialVersionUID = 8794429243621064597L;

	private static PayRollRepository PayRollRepository;

	// 会计期间
	@ManyToOne
	@JoinColumn(name = "fiscal_period_id")
	private FiscalPeriod fiscalPeriod;

	// 薪资帐套
	@ManyToOne
	@JoinColumn(name = "salary_accountsuite_id")
	private SalaryAccountSuite salaryAccountSuite;

	// 薪水册创建时间
	@Column(name = "created_time")
	@Temporal(TemporalType.TIMESTAMP)
	private Date created;

	public PayRoll() {
	}

	public PayRoll(SalaryAccountSuite salaryAccountSuite,
			FiscalPeriod fiscalPeriod, Date created) {
		this.fiscalPeriod = fiscalPeriod;
		this.salaryAccountSuite = salaryAccountSuite;
		this.created = created;
	}

	public static PayRollRepository getPayRollRepository() {
		if (PayRollRepository == null) {
			PayRollRepository = InstanceFactory
					.getInstance(PayRollRepository.class);
		}
		return PayRollRepository;
	}

	public static void setPayRollRepository(PayRollRepository payRollRepository) {
		PayRollRepository = payRollRepository;
	}

	public FiscalPeriod getFiscalPeriod() {
		return fiscalPeriod;
	}

	public void setFiscalPeriod(FiscalPeriod fiscalPeriod) {
		this.fiscalPeriod = fiscalPeriod;
	}

	public SalaryAccountSuite getSalaryAccountSuite() {
		return salaryAccountSuite;
	}

	public void setSalaryAccountSuite(SalaryAccountSuite salaryAccountSuite) {
		this.salaryAccountSuite = salaryAccountSuite;
	}

	public Date getCreated() {
		return created;
	}

	public void setCreated(Date created) {
		this.created = created;
	}

	@Override
	public boolean equals(Object obj) {
		if (obj instanceof PayRoll == false) {
			return false;
		}
		if (this == obj) {
			return true;
		}
		PayRoll rhs = (PayRoll) obj;
		return new EqualsBuilder().append(fiscalPeriod.getId(),
				rhs.getFiscalPeriod().getId())
				.append(salaryAccountSuite.getId(),
						rhs.getSalaryAccountSuite().getId()).isEquals();
	}

	@Override
	public int hashCode() {
		return new HashCodeBuilder(17, 37).append(fiscalPeriod.getId()).append(
				salaryAccountSuite.getId()).toHashCode();
	}

	@Override
	public String toString() {
		return ToStringBuilder.reflectionToString(this,
				ToStringStyle.SHORT_PREFIX_STYLE);
	}

	/*
	 * =======================================
	 * 
	 * action
	 * 
	 * ========================================
	 */

	public void save() {
		if (isNew()) {
			setCreated(new Date());
		}
		getPayRollRepository().save(this);
	}

	/**
	 * 删除薪水册，及其以下的所有薪资档案
	 */
	public void remove() {
		getPayRollRepository().removeAll(this);
	}

	/**
	 * 得到薪水册所归属的机构
	 * 
	 * @return
	 */
	public Organization getOrganization() {
		return SalaryAccountSuite.get(salaryAccountSuite.getId(), created)
				.getOrg();
	}

	public static PayRoll get(Long id) {
		return getPayRollRepository().get(id);
	}

	public static boolean isAlreadyExist(SalaryAccountSuite salaryAccountSuite,
			FiscalPeriod fiscalPeriod) {
		return getPayRollRepository().isAlreadyUsed(salaryAccountSuite,
				fiscalPeriod);
	}

	/**
	 * 指定薪资帐套，查找已产生薪水册的会计期间集合
	 * 
	 * @param accountSuite
	 * @return
	 */
	public static List<FiscalPeriod> findFiscalPeriodByAccountSuite(
			SalaryAccountSuite accountSuite) {
		return getPayRollRepository().findFiscalPeriodByAccountSuite(
				accountSuite);
	}

	/**
	 * 指定会计期间，查找已产生薪水册的薪资帐套集合
	 * 
	 * @param fiscalPeriod
	 * @return
	 */
	public static List<SalaryAccountSuite> findAccountSuiteByFiscalPeriod(
			FiscalPeriod fiscalPeriod) {
		return getPayRollRepository().findAccountSuiteByFiscalPeriod(
				fiscalPeriod);
	}

}
